import logging
from datetime import datetime
from typing import Dict, List, Optional, Callable

from db.entity2 import MatchDataV2

# Configure logger
logger = logging.getLogger(__name__)

class OddsMonitor:
    """
    赔率差异监控器
    用于检测 MatchDataV2 对象中的让球数变化
    """

    def __init__(self, threshold: float = 0.25):
        """
        :param threshold: 触发报警的让球数变化阈值，默认 0.25 球
        """
        self.threshold = threshold
        # 存储上一次的让球数 {match_id: handicap}
        self.last_handicaps: Dict[str, float] = {}
        # 报警回调函数列表
        self.alert_callbacks: List[Callable[[Dict], None]] = []
        
        # 缓存比赛的基本信息，用于报警时提供上下文 {match_id: {info}}
        self.match_info_cache: Dict[str, Dict] = {}

    def add_alert_callback(self, callback: Callable[[Dict], None]):
        """添加报警回调函数"""
        self.alert_callbacks.append(callback)

    def check_and_update(self, matches: List[MatchDataV2]) -> List[Dict]:
        """
        检查传入的比赛列表，对比之前的让球数，返回生成的报警列表
        并更新内部状态
        """
        alerts = []
        
        for match in matches:
            mid = match.比赛ID
            current_handicap = match.让球数
            
            # 缓存基本信息
            self.match_info_cache[mid] = {
                'league': match.联赛名_简体,
                'home': match.主队名_简体,
                'away': match.客队名_简体,
                'score': f"{match.主队比分}-{match.客队比分}",
                'time': match.比赛时间
            }

            # 检查是否存在历史数据
            if mid in self.last_handicaps:
                last_handicap = self.last_handicaps[mid]
                
                # 计算差异 (处理 None 的情况，虽然 MatchDataV2 默认 0.0)
                # 注意：有些比赛可能没有开盘，让球数为 0.0，这种变化通常忽略，或者视业务需求而定
                # 这里假设 0.0 -> 非0.0 也是变化
                
                diff = abs(current_handicap - last_handicap)
                
                if diff >= self.threshold:
                    # 生成报警
                    alert = {
                        'match_id': mid,
                        'league': match.联赛名_简体,
                        'home': match.主队名_简体,
                        'away': match.客队名_简体,
                        'type': '让球变化',
                        'old_val': last_handicap,
                        'new_val': current_handicap,
                        'diff': diff,
                        'time': datetime.now().strftime("%H:%M:%S"),
                        'message': f"[{match.联赛名_简体}] {match.主队名_简体} vs {match.客队名_简体}: 盘口从 {last_handicap} 变为 {current_handicap}"
                    }
                    alerts.append(alert)
                    logger.info(f"Monitor Alert: {alert['message']}")
            
            # 更新记录
            self.last_handicaps[mid] = current_handicap

        # 触发回调
        if alerts:
            self.trigger_alerts(alerts)
            
        return alerts

    def trigger_alerts(self, alerts: List[Dict]):
        """触发所有注册的回调"""
        for alert in alerts:
            for callback in self.alert_callbacks:
                try:
                    callback(alert)
                except Exception as e:
                    logger.error(f"Error in alert callback: {e}")

# 全局单例模式（可选）
_monitor_instance = None

def get_monitor_instance() -> OddsMonitor:
    global _monitor_instance
    if _monitor_instance is None:
        _monitor_instance = OddsMonitor()
    return _monitor_instance
